#include <iostream>
#include <unistd.h>
#include <pthread.h>
using namespace std;

// ====== 验证全局对象在程序加载前就会被初始化 ======
// class Singleton
// {
// public:
//     Singleton()
//         : _a(1), _b(1)
//     {
//         cout << "a + b = " << _a + _b << endl;
//     }

// private:
//     int _a;
//     int _b;
// };

// Singleton s1;
// Singleton s2;
// Singleton s3;

// int main()
// {
//     sleep(3);
//     return 0;
// }

// ====== 饿汉模式 ======
// class Singleton
// {
// private:
//     // 构造函数私有化
//     Singleton() {}

//     // 删除拷贝构造函数
//     Singleton(const Singleton &) = delete;

//     // 删除赋值操作符
//     Singleton &operator=(const Singleton &) = delete;

// public:
//     // 获取单例对象的句柄
//     static Singleton *getInstance()
//     {
//         return &_ptr;
//     }

//     void run()
//     {
//         cout << "void run()" << endl;
//     }

// private:
//     // 静态单例对象
//     static Singleton _ptr;
// };
// // 静态成员变量需要在类外初始化
// Singleton Singleton::_ptr;

// int main()
// {
//     Singleton *s1 = Singleton::getInstance();
//     s1->run();

//     return 0;
// }

// ====== 懒汉模式 ======
#include <iostream>
#include <unistd.h>
#include <pthread.h>
using namespace std;

class Singleton
{
private:
    // 私有构造函数
    Singleton() {}

    // 删除拷贝构造函数
    Singleton(const Singleton &) = delete;

    // 删除赋值操作符
    Singleton &operator=(const Singleton &) = delete;

public:
    // 获取单例对象的句柄
    static Singleton *getInstance()
    {
        if (_ptr == nullptr)
        {
            pthread_mutex_lock(&_mtx);
            if (_ptr == nullptr)
            {
                std::cout << "创建了一个单例对象" << std::endl;
                _ptr = new Singleton();
            }
            pthread_mutex_unlock(&_mtx);
        }

        return _ptr;
    }

    // static Singleton *getInstance()
    // {
    //     if (_ptr == nullptr)
    //     {
    //         std::cout << "创建了一个单例对象" << std::endl;
    //         _ptr = new Singleton();
    //     }

    //     return _ptr;
    // }

    void run()
    {
        cout << "void run()" << endl;
    }

private:
    static Singleton *_ptr;
    static pthread_mutex_t _mtx;
};

// 静态成员变量需要在类外初始化
Singleton *Singleton::_ptr = nullptr;
pthread_mutex_t Singleton::_mtx = PTHREAD_MUTEX_INITIALIZER;

void *threadFunc(void *)
{
    // 获取句柄
    Singleton::getInstance()->run();
    return nullptr;
}

int main()
{
    pthread_t p[10];

    for (int i = 0; i < 10; i++)
    {
        pthread_create(p + i, nullptr, threadFunc, nullptr);
    }
    // 线程等待
    for (int i = 0; i < 10; i++)
    {
        pthread_join(p[i], nullptr);
    }
    return 0;
}
